unit RenderContext;

interface

uses Windows;

type
  TRenderContext = class
  private
    aWND: HWND;
    aRC: HGLRC;
    aDC: HDC;
  public
    constructor Create;
    destructor Destroy;override;
    function Init(paWND: HWND; paMakeActive: Boolean): Boolean;
    function Relase: Boolean;
    function MakeActive: Boolean;
    function Swap: Boolean;
  end;

implementation

constructor TRenderContext.Create;
begin
    inherited Create;
end;

destructor TRenderContext.Destroy;
begin
    inherited Destroy;
end;

function TRenderContext.Init(paWND: HWND; paMakeActive: Boolean): Boolean;
var PFD: PixelFormatDescriptor;
    PixelFormat: Cardinal;
begin
    aWND := paWND;
    with PFD do begin
        nSize:= SizeOf(PixelFormatDescriptor);
        nVersion:= 1;
        dwFlags:= PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
        iPixelType:= PFD_TYPE_RGBA;
        cColorBits:= 24;
        cRedBits:= 0;
        cRedShift:= 0;
        cGreenBits:= 0;
        cBlueBits:= 0;
        cBlueShift:= 0;
        cAlphaBits:= 0;
        cAlphaShift:= 0;
        cAccumBits:= 0;
        cAccumRedBits:= 0;
        cAccumGreenBits:= 0;
        cAccumBlueBits:= 0;
        cAccumAlphaBits:= 0;
        cDepthBits:= 24;
        cStencilBits:= 0;
        cAuxBuffers:= 0;
        iLayerType:= PFD_MAIN_PLANE;
        bReserved:= 0;
        dwLayerMask:= 0;
        dwVisibleMask:= 0;
        dwDamageMask:= 0;
    end;
    aDC := GetDC(aWND);
    if aDC = 0 then begin
        Result := false;
        Exit;
    end;
    PixelFormat := ChoosePixelFormat(aDC, @PFD);
    if PixelFormat = 0 then begin
        Result := false;
        Exit;
    end;
    if not SetPixelFormat(aDC, PixelFormat, @PFD) then begin
        Result := false;
        Exit;
    end;
    aRC := wglCreateContext(aDC);
    if (aRC = 0) then begin
        Result := false;
        Exit;
    end;
    if MakeActive then begin
        if not wglMakeCurrent(aDC, aRC) then begin
            Result := false;
            Exit;
        end;
    end;
    Result := true;
end;

function TRenderContext.Relase: Boolean;
begin
    if aRC <> 0 then begin
        if not wglMakeCurrent(aDC, 0) then begin
            Result := false;
            Exit;
        end;
        if not wglDeleteContext(aRC) then begin
            Result := false;
            Exit;
        end;
    end;
    if (aDC = 1) and (ReleaseDC(aWND, aDC) <> 0) then begin
        Result := false;
        Exit;
    end;
    Result := true;
end;

function TRenderContext.MakeActive: Boolean;
begin
    if not wglMakeCurrent(aDC, aRC) then begin
        Result := false;
        Exit;
    end;
    Result := true;
end;

function TRenderContext.Swap: Boolean;
begin
    Result := SwapBuffers(aDC);
end;

end.
